﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CompactFramework.Utilities.Localization;

namespace TripLOAMobile
{
    public partial class Config : LocalizedForm
    {
        private EventHandler updateDataHandler;
        private Bitmap m_DoubleBuffer; //Used to avoid flickering effects on paint procedure

        #region Initialization
        /// <summary>
        /// Initializes a new instance of the Config class.
        /// </summary>
        public Config()
        {
            InitializeComponent();
            #region DoubleBufferInitialization
            Size cSz = ClientSize;
            m_DoubleBuffer = new Bitmap(cSz.Width, cSz.Height);
            #endregion
            this.changeAnimationComboBox.Items.Add(CompactFramework.Utilities.Localization.ResourceManager.Instance.GetString("comboBoxAnimation_StdAppl"));
            this.changeAnimationComboBox.Items.Add(CompactFramework.Utilities.Localization.ResourceManager.Instance.GetString("comboBoxAnimation_StdMob"));

            this.AddMenusToDictionary();
            UpdateResources();

            if (ResourceManager.Instance.Culture.Name == "it-IT")
                this.langList.SelectedIndex = 0;
            else this.langList.SelectedIndex = 1;
            if (Welcome.gps.Opened)
                this.chkBoxGPS.Checked = true;            
            
            if (AnimationControl.USESTANDARDAPPLICATIONANIMATION)
                this.changeAnimationComboBox.SelectedIndex = 0;
            else
            {
                this.changeAnimationComboBox.SelectedIndex = 1;
                this.pictureBoxAnimationPreview.Image = TripLOAMobile.Properties.Resources.Win_1;
            }
            latDD.Visible = false;
            longDD.Visible = false;
            satCount.Visible = false;
            time.Visible = false;
        }

        /// <summary>
        /// The subclasses of the LocalizedForm should override this method and use this method to
        /// associate all menu items with custom names with the help of AddMenuToDictionary
        /// method.
        /// </summary>
        protected override void AddMenusToDictionary()
        {
            this.AddMenuToDictionary(this.menuLeft, "menuLeft");
        }

        /// <summary>
        /// Handles the Load event of the  control.
        /// Add the EventHandlers for the GPS, if the connection is opened, used to show the status of the GPS.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The EventArgs instance containing the event data.</param>
        private void _Load(object sender, System.EventArgs e)
        {
            if (Welcome.gps.Opened)
            {
                updateDataHandler = new EventHandler(UpdateData);
                Welcome.gps.DeviceStateChanged += new GPS.Gps.DeviceStateChangedEventHandler(updateDS);
                Welcome.gps.LocationChanged += new GPS.Gps.LocationChangedEventHandler(updateLC);
            }
        }

        /// <summary>
        /// Handles the Closed event of the  control.
        /// Remove the EventHandlers for the GPS if the connection is opened.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The EventArgs instance containing the event data.</param>
        private void _Closed(object sender, System.EventArgs e)
        {
            if (Welcome.gps.Opened)
            {
                Welcome.gps.DeviceStateChanged -= updateDS;
                Welcome.gps.LocationChanged -= updateLC;
            }
        }
        #endregion

        #region GPS Event Handlers
        /// <summary>
        /// Handles the LocationChanged event of the gps control.
        /// Updates the GPS position
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="args">The LocationChangedEventArgs instance containing the event data.</param>
        public void gps_LocationChanged(object sender, GPS.LocationChangedEventArgs args)
        {
            Welcome.gps.Position = args.Position;
        }

        /// <summary>
        /// Handles the DeviceStateChanged event of the gps control.
        /// Updates the device state of the GPS.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="args">The DeviceStateChangedEventArgs instance containing the event data.</param>
        public void gps_DeviceStateChanged(object sender, GPS.DeviceStateChangedEventArgs args)
        {
            Welcome.gps.DeviceState = args.DeviceState;
        }
        #endregion

        #region GPS Update Handler
        /// <summary>
        /// Used to invoke the Handler to update the GPS Device State.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The DeviceStateChangedEventArgs instance containing the event data.</param>
        protected void updateDS(object sender, GPS.DeviceStateChangedEventArgs args)
        {
            Invoke(updateDataHandler);
        }

        /// <summary>
        /// Used to invoke the Handler to update the GPS position.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The LocationChangedEventArgs instance containing the event data.</param>
        protected void updateLC(object sender, GPS.LocationChangedEventArgs args)
        {
            Invoke(updateDataHandler);
        }

        /// <summary>
        /// Shows the status of the GPS.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The EventArgs instance containing the event data.</param>
        void UpdateData(object sender, System.EventArgs args)
        {
            if (Welcome.gps.Opened)
            {
                if (Welcome.gps.DeviceState != null)
                {
                    lblGpsInfo.Text = Welcome.gps.DeviceState.FriendlyName + " " + Welcome.gps.DeviceState.ServiceState + ", " + Welcome.gps.DeviceState.DeviceState;
                }

                if (Welcome.gps.Position != null)
                {

                    if (Welcome.gps.Position.LatitudeValid)
                    {
                        latDD.Text = Welcome.gps.Position.Latitude.ToString();
                    }

                    if (Welcome.gps.Position.LongitudeValid)
                    {
                        longDD.Text = Welcome.gps.Position.Longitude.ToString();
                    }

                    if (Welcome.gps.Position.SatellitesInSolutionValid &&
                        Welcome.gps.Position.SatellitesInViewValid &&
                        Welcome.gps.Position.SatelliteCountValid)
                    {
                        satCount.Text = Welcome.gps.Position.GetSatellitesInSolution().Length + "/" +
                            Welcome.gps.Position.GetSatellitesInView().Length + " (" +
                            Welcome.gps.Position.SatelliteCount + ")";
                    }

                    if (Welcome.gps.Position.TimeValid)
                    {
                        time.Text = Welcome.gps.Position.Time.ToString();
                    }
                }
            }
        }
        #endregion

        #region Event Handling
        /// <summary>
        /// Handles the CheckStateChanged event of the checkBox1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The EventArgs instance containing the event data.</param>
        private void checkBox1_CheckStateChanged(object sender, EventArgs e)
        {
            if (chkBoxGPS.Checked)
            {
                lblLatDD.Visible = true;
                lblLongDD.Visible = true;
                lblSat.Visible = true;
                lblTime.Visible = true;
                latDD.Visible = true;
                longDD.Visible = true;
                satCount.Visible = true;
                time.Visible = true;
                Welcome.gps.Open();
                updateDataHandler = new EventHandler(UpdateData);
                Welcome.gps.DeviceStateChanged += new GPS.Gps.DeviceStateChangedEventHandler(gps_DeviceStateChanged);
                Welcome.gps.LocationChanged += new GPS.Gps.LocationChangedEventHandler(gps_LocationChanged);
                Welcome.gps.DeviceStateChanged += new GPS.Gps.DeviceStateChangedEventHandler(updateDS);
                Welcome.gps.LocationChanged += new GPS.Gps.LocationChangedEventHandler(updateLC);
            }
            else
            {
                lblGpsInfo.Text = "";
                lblLatDD.Visible = false;
                lblLongDD.Visible = false;
                lblSat.Visible = false;
                lblTime.Visible = false;
                latDD.Visible = false;
                longDD.Visible = false;
                satCount.Visible = false;
                time.Visible = false;
                Welcome.gps.Close();
                Welcome.gps.DeviceStateChanged -= gps_DeviceStateChanged;
                Welcome.gps.LocationChanged -= gps_LocationChanged;
                Welcome.gps.DeviceStateChanged -= updateDS;
                Welcome.gps.LocationChanged -= updateLC;
            }
        }

        /// <summary>
        /// Handles the SelectedIndexChanged event of the langList control.
        /// Used to modify the language of the application.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The EventArgs instance containing the event data.</param>
        private void langList_SelectedIndexChanged(object sender, EventArgs e)
        {
            ResourceManager.Instance.Culture = new System.Globalization.CultureInfo(((ComboBox)sender).SelectedItem.ToString());
            #region localize
            int app = this.changeAnimationComboBox.SelectedIndex;
            this.changeAnimationComboBox.Items[0] = CompactFramework.Utilities.Localization.ResourceManager.Instance.GetString("comboBoxAnimation_StdAppl");
            this.changeAnimationComboBox.Items[1] = CompactFramework.Utilities.Localization.ResourceManager.Instance.GetString("comboBoxAnimation_StdMob");
            this.changeAnimationComboBox.SelectedIndex = app;
            #endregion
            Welcome.rrp.SetUserLanguage(((ComboBox)sender).SelectedItem.ToString());
        }

        /// <summary>
        /// Handles the SelectedIndexChanged event of the changeAnimationComboBox control.
        /// Used to change the type of the animation.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The EventArgs instance containing the event data.</param>
        private void changeAnimationComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            //0= standard application animation, 1= standard mobile animation
            ComboBox cb = (ComboBox)sender;
            if (cb.SelectedIndex == 0)
            {
                AnimationControl.USESTANDARDAPPLICATIONANIMATION = true;
                this.pictureBoxAnimationPreview.Image = TripLOAMobile.Properties.Resources.Win_1b;
            }
            else if (cb.SelectedIndex == 1)
            {
                this.pictureBoxAnimationPreview.Image = TripLOAMobile.Properties.Resources.Win_1;
                AnimationControl.USESTANDARDAPPLICATIONANIMATION = false;
            }
            Welcome.rrp.SetUserAnimationTheme(AnimationControl.USESTANDARDAPPLICATIONANIMATION);
        }

        /// <summary>
        /// Handles the Click event of the menuLeft(back) control.
        /// Remove the handler used to update the GPS status.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The EventArgs instance containing the event data.</param>
        private void menuLeft_Click(object sender, EventArgs e)
        {
            Welcome.gps.DeviceStateChanged -= updateDS;
            Welcome.gps.LocationChanged -= updateLC;
            Welcome.formBuffer.Close();
        }
        #endregion

        #region OnPaint
        /// <summary>
        /// Handles the Paint event.
        /// </summary>
        /// <param name="e">A PaintEventArgs that contains the event data.</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            WinAPI.ShowDoneButton(this.Handle, false);
            base.OnPaint(e);
        }

        /// <summary>
        /// Handles the Paint event of the gpsTab control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The PaintEventArgs instance containing the event data.</param>
        private void gpsTab_Paint(object sender, PaintEventArgs e)
        {
            using (Graphics g = Graphics.FromImage(m_DoubleBuffer))
            {
                g.Clear(gpsTab.BackColor);
                g.DrawImage(Properties.Resources.circles, 3, AutoScrollPosition.Y + 3);
                Point[] p = new Point[]{
                    new Point(40,AutoScrollPosition.Y + 25), 
                    new Point(195,AutoScrollPosition.Y + 25), 
                    new Point(190,AutoScrollPosition.Y + 30), 
                    new Point(40,AutoScrollPosition.Y + 30)};
                using (Brush b = new SolidBrush(Color.Green))
                    g.FillPolygon(b, p);

                p[0].Y = p[1].Y = AutoScrollPosition.Y + 30;
                p[2].Y = p[3].Y = AutoScrollPosition.Y + 35;
                p[1].X -= 10;
                p[2].X -= 10;
                using (Brush b = new SolidBrush(Color.GreenYellow))
                    g.FillPolygon(b, p);

                g.DrawImage(Properties.Resources.circles, 3, AutoScrollPosition.Y + 75);

                p = new Point[]{
                    new Point(40,AutoScrollPosition.Y + 97), 
                    new Point(195,AutoScrollPosition.Y + 97), 
                    new Point(190,AutoScrollPosition.Y + 102), 
                    new Point(40,AutoScrollPosition.Y + 102)};
                using (Brush b = new SolidBrush(Color.Green))
                    g.FillPolygon(b, p);

                p[0].Y = p[1].Y = AutoScrollPosition.Y + 102;
                p[2].Y = p[3].Y = AutoScrollPosition.Y + 107;
                p[1].X -= 10;
                p[2].X -= 10;
                using (Brush b = new SolidBrush(Color.GreenYellow))
                    g.FillPolygon(b, p);
            }
            using (Graphics g = e.Graphics)
                g.DrawImage(m_DoubleBuffer, 0, 0);
        }

        /// <summary>
        /// Handles the Paint event of the settingsTab control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The PaintEventArgs instance containing the event data.</param>
        private void settingsTab_Paint(object sender, PaintEventArgs e)
        {
            using (Graphics g = Graphics.FromImage(m_DoubleBuffer))
            {
                g.Clear(settingsTab.BackColor);
                g.DrawImage(Properties.Resources.circles, 3, AutoScrollPosition.Y + 3);
                Point[] p = new Point[]{
                    new Point(40,AutoScrollPosition.Y + 25), 
                    new Point(195,AutoScrollPosition.Y + 25), 
                    new Point(190,AutoScrollPosition.Y + 30), 
                    new Point(40,AutoScrollPosition.Y + 30)};
                using (Brush b = new SolidBrush(Color.Green))
                    g.FillPolygon(b, p);

                p[0].Y = p[1].Y = AutoScrollPosition.Y + 30;
                p[2].Y = p[3].Y = AutoScrollPosition.Y + 35;
                p[1].X -= 10;
                p[2].X -= 10;
                using (Brush b = new SolidBrush(Color.GreenYellow))
                    g.FillPolygon(b, p);

                g.DrawImage(Properties.Resources.circles, 3, AutoScrollPosition.Y + 77);

                p = new Point[]{
                    new Point(40,AutoScrollPosition.Y + 99), 
                    new Point(195,AutoScrollPosition.Y + 99), 
                    new Point(190,AutoScrollPosition.Y + 104), 
                    new Point(40,AutoScrollPosition.Y + 104)};
                using (Brush b = new SolidBrush(Color.Green))
                    g.FillPolygon(b, p);

                p[0].Y = p[1].Y = AutoScrollPosition.Y + 104;
                p[2].Y = p[3].Y = AutoScrollPosition.Y + 109;
                p[1].X -= 10;
                p[2].X -= 10;
                using (Brush b = new SolidBrush(Color.GreenYellow))
                    g.FillPolygon(b, p);
            }
            using (Graphics g = e.Graphics)
                g.DrawImage(m_DoubleBuffer, 0, 0);
        }
        #endregion
    }
}